package com.hertz.appr.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.hertz.appr.cache.Cache;
import com.hertz.appr.cache.CacheFactory;
import com.hertz.appr.pojo.CmdPojo;
import com.hertz.appr.pojo.Mentions;
import com.hertz.appr.pojo.Paging;
import com.hertz.appr.pojo.db.Message;
import com.hertz.appr.service.cmd.v1.CmdPojoFactory;
import com.hertz.appr.util.Configuration;
import com.hertz.appr.util.PropertiesHelper;

public class MentionsService {
	private Logger log = Logger.getLogger(MentionsService.class);
	
	private Mentions mentions;
	private String provider;
	private ActionService actionService;
	private TaskService taskService;
	private CmdPojoFactory cmdPojoFactory;
	private CacheFactory cacheFactory;
	
	public MentionsService(String provider){
		this.provider = provider;
	}
	
	/**
	 * 在规定的times内，最多访问counts次api，从since标识起
	 * 顺时针翻页
	 * @param since		起始标识，id或时间戳
	 * @param counts	访问api的次数
	 * @param times		时间,毫秒数
	 * @return
	 */
	public List<Message> getMentionsNext(Long since,int counts,int times){
		if(provider.equals(Configuration.SINA_PROVIDER)){
			return getMentions4Sina(since,counts,times);
		}else{
			Paging page = new Paging(provider,true,since);
			List<Message> result = new ArrayList<Message>();
//			List<Twitter> questionTwitters = new ArrayList<Twitter>();
//			List<Twitter> messageTwitters = new ArrayList<Twitter>();
//			List<Twitter> ansTwitters = new ArrayList<Twitter>();
			Long border = since;
			
			try {
				long startTime = System.currentTimeMillis();
				for(int i = 0; i < counts; i++){
					if(System.currentTimeMillis() - startTime >= times){
						log.info("top of api limit,so break");
						break;
					}
					List<Message> list = mentions.getMentions(page);
					if(list == null || list.size() == 0)
						break;
					result.addAll(list);
					border = getTopBorder(list);
					log.debug("this page's border = " + border);
					page.setBorder(border);
					if(list.size() < page.getPageSize()){
						break;
					}
				}
//				setBorder4NextSince(border);
			} catch (Exception e) {
				// TODO: handle exception
				log.error("getMentions error : " + e.getMessage());
				e.printStackTrace();
			}
			Collections.sort(result);
			return result;
		}
		
	}
	
	public List<Message> getMentions4Sina(Long since,int counts,int times){
		List<Message> result = new ArrayList<Message>();
		String maxIdKey = "";
		PropertiesConfiguration config = PropertiesHelper.getConfiguration();
//		Object o = config.getProperty(provider + "_mentions_max_border");
		maxIdKey = config.getString(provider + "_mentions_max_border");
		Cache cache = null;
		if(StringUtils.isNotBlank(maxIdKey)){
			log.debug("get messages from cache,maxIdKey = " + maxIdKey);
			cache = cacheFactory.buildCache("sinaMessageHistoryRegion");
			List<Message> list = (List<Message>)cache.get(provider + "-" + maxIdKey);
			if(list != null && list.size() != 0)
				result.addAll(list);
		}
		Paging page = new Paging(provider,false,null);
		page.setPageSize(Paging.pageSize4Sina);
		Long border = null;
		
		try {
			long startTime = System.currentTimeMillis();
			boolean isOk = false;
			for(int i = 0; i < counts; i++){
				if(System.currentTimeMillis() - startTime >= times){
					log.info("top of api limit,so break");
					break;
				}
				if(i == 0){
					page.setPageNum4Sina(result.size() / Paging.pageSize4Sina);
					page.nextPageNum4Sina();
				}
				List<Message> list = mentions.getMentions(page);
				if(list == null || list.size() == 0)
					break;
				if(i == 0){
					Message topMsg = getTopMessage(list);
					border = Long.valueOf(topMsg.getTid());
					page.setBorder(border);
				}
				log.debug("this page's border id = " + border);
				if(since == 0L){
					result.addAll(list);
				}else{
					for(Message msg : list){
						if(msg.getTid().equals(since.toString())){
							isOk = true;
							break;
						}else{
							result.add(msg);
						}
					}
				}
				page.nextPageNum4Sina();
				if(list.size() < page.getPageSize()){
					isOk = true;//到头了。
					break;
				}
			}
//			if(since == 0L){
//				isOk = true;
//			}
			if(isOk){//设置下次执行的sincId,清空cache，清空sina_mentions_max_border， 否则，保留
				if(cache != null)
					cache.remove(maxIdKey);
				config.setProperty(provider + "_mentions_max_border","");
			}else{
				if(cache != null){
					cache.put(provider + "-" + maxIdKey, result);
				}
//				config.setProperty(provider + "_mentions_max_border",border.toString());
			}
//			setBorder4NextSince(border);
		} catch (Exception e) {
			// TODO: handle exception
			log.error("getMentions error : " + e.getMessage());
			e.printStackTrace();
		}
		Collections.sort(result);
		return result;
	}
	
	public long getBottomBorderId(List<Message> list){
		Collections.sort(list);
		return list.get(0).getId();
	}
	
	public Message getTopMessage(List<Message> list){
		Collections.sort(list);
		//腾讯的时间戳是10位，系统时间戳是13位
		return list.get(list.size() - 1);
	}
	
	public long getTopBorder(List<Message> list){
		Collections.sort(list);
		//腾讯的时间戳是10位，系统时间戳是13位
		return list.get(list.size() - 1).getCreateTimeShort();
	}
	public void setBorder4NextSince(Long border){
		PropertiesConfiguration config = PropertiesHelper.getConfiguration();
		log.debug(provider + "_mentions_border=" + config.getLong(provider + "_mentions_border"));
		config.setProperty(provider + "_mentions_border", border);
		log.debug("set appr-variables.properties, " + provider + "_mentions_border=" + border); 
	}
	
	public void setBorder4NextSince(Message msg){
		Long border = msg.getCreateTimeShort();
		if(provider.equals(Configuration.SINA_PROVIDER)){
			border = Long.valueOf(msg.getTid());
		}
		PropertiesConfiguration config = PropertiesHelper.getConfiguration();
		log.debug(provider + "_mentions_border=" + config.getLong(provider + "_mentions_border"));
		config.setProperty(provider + "_mentions_border", border);
		log.debug("set appr-variables.properties, " + provider + "_mentions_border=" + border); 
	}
	
	public void fill2DB(List<Message> list){
		log.debug("start fill message 2 DB");
		for(Message msg : list){
			CmdPojo cmdPojo = null;
			try {
				cmdPojo = cmdPojoFactory.buildCmdPojo(msg);
				if(cmdPojo == null){
					log.debug("buildCmdPojo return null");
				}else if(cmdPojo.getRes().equals("ok")){
					cmdPojoFactory.dealMessage(msg, cmdPojo);
				}
			} catch (Exception e) {
				log.error("parase this cmd error : text = " + msg.getOrigtext());
				log.error("sourceText = " + (msg.getSourceTwitter() != null? msg.getSourceTwitter().getOrigtext():""));
				taskService.buildWarningTask(msg);
				e.printStackTrace();
			}
			
			//腾讯的时间戳是10位，系统时间戳是13位
			setBorder4NextSince(msg);
		}
		
	}
	
	public ActionService getActionService() {
		return actionService;
	}

	public void setActionService(ActionService actionService) {
		this.actionService = actionService;
	}

	public String getProvider() {
		return provider;
	}

	public void setProvider(String provider) {
		this.provider = provider;
	}

	public Mentions getMentions() {
		return mentions;
	}

	public void setMentions(Mentions mentions) {
		this.mentions = mentions;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public CmdPojoFactory getCmdPojoFactory() {
		return cmdPojoFactory;
	}

	public void setCmdPojoFactory(CmdPojoFactory cmdPojoFactory) {
		this.cmdPojoFactory = cmdPojoFactory;
	}
	public CacheFactory getCacheFactory() {
		return cacheFactory;
	}

	public void setCacheFactory(CacheFactory cacheFactory) {
		this.cacheFactory = cacheFactory;
	}
	
}
